home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / hamradio / sgp4_pl2.zip / SGP4-PLB.ITF < prev    next >
Text File  |  1992-10-01  |  39KB  |  826 lines

  1.                               Documentation for
  2.                              NORAD SGP4/SDP4 Units
  3.  
  4.                            Interface Specifications
  5.  
  6.                                  Developed by
  7.                                   Dr TS Kelso
  8.  
  9.                                  Version 2.50
  10.                                 1992 October 01
  11.  
  12. Copyright (C) 1992.  All rights reserved.
  13.  
  14.  
  15. INTRODUCTION
  16.  
  17. The following document is intended to provide complete documentation for the
  18. interface section of the units provided in this package.  Each unit will be
  19. presented, in alphabetical order, and the INTERFACE section is reproduced,
  20. showing the exact nature of each call.  Following this information will be a
  21. description of the intended use of each variable and procedure.
  22.  
  23. ** UNIT MINMAX -- VERSION 1.02 ***********************************************
  24.  
  25. Function IMin(arg1,arg2 : integer) : integer;
  26. Function IMax(arg1,arg2 : integer) : integer;
  27. Function RMin(arg1,arg2 : real) : real;
  28. Function RMax(arg1,arg2 : real) : real;
  29. Function DMin(arg1,arg2 : double) : double;
  30. Function DMax(arg1,arg2 : double) : double;
  31.  
  32. These functions are used to provide integer, real, and double minimum and
  33. maximum calculations used in the libraries.
  34.  
  35. ** UNIT SGP4SDP4 -- VERSION 1.50 *********************************************
  36.  
  37.   Uses Support,
  38.        SGP_Init,
  39.        SGP_Math,SGP_Time;
  40.  
  41. Procedure SGP(time : double;
  42.        var pos,vel : vector);
  43. Procedure SGP4(tsince : double;
  44.             var iflag : integer;
  45.           var pos,vel : vector);
  46. Procedure SDP4(tsince : double;
  47.             var iflag : integer;
  48.           var pos,vel : vector);
  49.  
  50. This unit contains the Pascal implementation of the SGP4 and SDP4 orbital
  51. models.  Two methods of interfacing are available.  The first method is to
  52. access the individual routines exactly as described in Project Spacetrack
  53. Report Number 3 (Procedures SGP4 and SDP4).  This method requires the user to
  54. calculate the time (in minutes) since each satellite element set epoch and
  55. determine the appropriate model to use.  The variable {iflag} is used to keep
  56. track of initialization status and is set within these routines and within
  57. Convert_Satellite_Data (Unit SGP_CONV).  This method is *NOT* recommended.
  58.  
  59. The second method is to access the orbital models via a call to SGP.  Here the
  60. user is only required to pass a time (Julian Date) for the calculation and the
  61. satellite ECI position and velocity are returned.  Determination of the
  62. appropriate orbital model is transparent to the user.  The only requirement is
  63. that a call to Convert_Satellite_Data be made each time a new satellite is
  64. selected before calling SGP.  Routines for calculating Julian Dates are
  65. included in Unit SGP_TIME.
  66.  
  67. ** UNIT SGP_CONV -- VERSION 1.00 *********************************************
  68.  
  69.   Uses SGP_Math;
  70.  
  71. Procedure Convert_Satellite_Data(arg : integer);
  72. Procedure Convert_Sat_State(var pos,vel : vector);
  73.  
  74. The first procedure is used to extract the data in a given two-line element
  75. set to the variables expected by UNIT SGP4SDP4.  The data structures
  76. containing the two-line element sets is described in UNIT SGP_INIT.  In
  77. addition, a determination as to whether the near-earth (SGP4) or deep-space
  78. (SDP4) model should be used is made within this unit.  These variables are
  79. passed between SGP4SDP4 and SGP_CONV using UNIT SGP_INTF.  This unit
  80. (SGP_INTF) should NOT be included in the main program unless absolutely
  81. necessary to avoid unintentional changes to these critical variables.  Two
  82. additional variables, {catnr} and {elset}, are provided to identify the
  83. satellite element set.  Finally, the variable {epoch} is globally available to
  84. determine the epoch of the element set.
  85.  
  86. Convert_Sat_State is used to convert the native units provided by SGP4/SDP4
  87. (position in earth radii, velocity in earth radii/minute) to standard metric
  88. units (kilometers and kilometers/sec).
  89.  
  90. ** UNIT SGP_IN -- VERSION 2.00 ***********************************************
  91.  
  92. (** This unit contains machine-specific code **)
  93.  
  94.   Uses SGP_Math,SGP_Init,Support;
  95.  
  96. const
  97.   data_type : byte = 3;
  98.  
  99. var
  100.   fsat,fobs : text;
  101.  
  102. Procedure Select_Time(message : string;
  103.                     xpos,ypos : byte;
  104.                   var default : time_set;
  105.                     precision : byte);
  106. Procedure Select_Time_Interval(message : string;
  107.                              xpos,ypos : byte;
  108.                            var default : time_set;
  109.                              precision : byte);
  110. Function Checksum_Good(line : line_data) : boolean;
  111. Function Good_Elements(lines : two_line) : boolean;
  112. Procedure Input_Satellite(index : word);
  113. Function Input_Satellite_Data(fn : string) : word;
  114. Procedure Select_Satellites(title : string;
  115.                           x,y,w,h : byte;
  116.                            number : word);
  117. Procedure Input_Observer(var geodetic : vector);
  118.  
  119. This unit is one of two units which contain machine-specific code; this
  120. limitation will probably be removed in the future, moving all machine-specific
  121. code to UNIT SUPPORT.
  122.  
  123. The constant {data_type} is preset to 3 and is used to specify the format of
  124. the two-line orbital data file.  A value of 2 indicates that the satellite
  125. data files contain *only* two-line data; a value of 3 indicates that each two-
  126. line element set is preceded by a 22-character satellite name.  These data are
  127. read into data structures as described in UNIT SGP_INIT.  The value of
  128. {data_type} can be changed in the main program and, if necessary, should be
  129. done within the program initialization block.
  130.  
  131. The variables {fsat} and {fobs} are predefined text files to be assigned to
  132. the satellite and observer files, respectively.  Routines used in this unit
  133. expect to use these file handles.
  134.  
  135. The first two procedures, Select_Time and Select_Time_Interval, are provided
  136. to make it easy to input start/stop times and time intervals for performing
  137. calculations.  Each procedure will put a window on the screen with the title
  138. specified by {message} at the location ({xpos},{ypos}).  A default time set is
  139. passed to initialize the time; the structure of this variable is set forth in
  140. UNIT SUPPORT.  The variable {default} may be initialized manually or by a call
  141. to Get_Current_Time (for Select_Time) or Zero_Time (for Select_Time_Interval);
  142. each of these procedures is also in UNIT SUPPORT.  The variable {precision} is
  143. used to indicate the precision of the data to be selected.  Precision ranges
  144. from years down to hundredths of a second.  A precision of 7 indicates that
  145. all time units are to be input; a precision of 5 would omit inputting seconds
  146. and hundredths of seconds.  All values beyond the specified precision are set
  147. to zero, regardless of any other user action.
  148.  
  149. The next two functions are used to determine whether a given two-line element
  150. set is "good" -- at least in the sense that it passes the modulo-10 checksum
  151. on each line and that all the numbers appear to be in the proper fields.  A
  152. simple call passing the two-line element set {lines} to Good_Elements returns
  153. TRUE if the data passes these tests.  The function Checksum_Good can be used
  154. to test the modulo-10 checksum for a single line of a two-line element set.
  155. These functions are not used explicitly during element set input as it is
  156. assumed that the user has already done so (all data that I post has already
  157. been subjected to these tests).  In fact, the program PASSUPDT, which is
  158. available on this system for updating files of two-line element sets from a
  159. master file, does this checking for you.  However, if you are unsure of the
  160. quality of your data, it is STRONGLY RECOMMENDED that you develop your own
  161. preprocessor using these functions to test your data.
  162.  
  163. The procedure Input_Satellite is used to read in individual two-line element
  164. sets.  The index indicates its placement within the data array.  This call
  165. assumes that {fsat} has already been ASSIGNed and initialized.  Typically,
  166. this call is made from the function Input_Satellite_Data which initializes
  167. {fsat} and reads an entire file into memory from the file {fn}; the output of
  168. this function is the number of satellites in {fn}.  However, due to memory
  169. limitations, some files will be too large to read into memory.  In these
  170. cases, Input_Satellite should be used to sequentially read and process
  171. individual element sets; each element set could be read into {index}=1 and
  172. processed before proceeding.
  173.  
  174. In cases where all the orbital data can be read into memory and {data_type}=3,
  175. the procedure Select_Satellites can be used to tag satellites for calculations
  176. later in the program using the array {selected}.  Initially, no satellites are
  177. selected.  A call to this procedure will place a window on the screen with the
  178. upper-left corner at ({x},{y}) and having a width {w} and maximum height {h}
  179. (the height ranges from 1 to the minimum of {h} and the number of satellites).
  180. A {title} is also put on the window.  The final parameter in this call is the
  181. number of satellites available.  Selection is achieved by moving with the
  182. up/down cursor keys to the appropriate satellite and toggling with the space
  183. bar (an asterisk marks an item as being selected); data scrolls in the window
  184. as necessary.  Toggling advances to the next item in the list, making it
  185. easier to quickly mark items.  The 'A' key toggles All items (negates their
  186. current status).  Once the desired items are selected, the [ENTER] key
  187. completes the process.  Within the main program, items can be tested for
  188. selection with a statement such as:  if selected[index] then ...
  189.  
  190. The final procedure for this unit is Input_Observer and it works somewhat like
  191. Input_Satellite except that the data is read into a {geodetic} four-vector
  192. where {geodetic}[1] is North latitude, {geodetic}[2] is East longitude (that
  193. means that West longitudes are negative), and {geodetic}[3] is altitude above
  194. mean sea level (AMSL).  Input is expected from the file {fobs} in units of
  195. degrees and meters but is immediately converted to radians and kilometers for
  196. use within these units.  Each observer entry in {fobs} consists of a single
  197. line beginning with a 25-character site name (passed as {obs_name}); it is
  198. expected that this name has a three-character short name (or number), two
  199. spaces, followed by a long name.  The short name is used within UNIT SGP_OUT
  200. for topocentric output.  The remaining three numbers on this line are free-
  201. field format, beginning on or after character 26.
  202.  
  203. ** UNIT SGP_INIT -- VERSION 1.10 *********************************************
  204.  
  205. const
  206.   max_sats = 250;
  207.  
  208. type
  209.   line_data = string[69];
  210.   two_line  = array [1..2] of line_data;
  211.  
  212. var
  213.   visible              : boolean;
  214.   epoch                : double;
  215.   catnr,elset          : string;
  216.   obs_name             : string[25];
  217.   selected             : array [1..max_sats] of boolean;
  218.   sat_name             : array [1..max_sats] of string[22];
  219.   sat_data             : array [1..max_sats] of two_line;
  220.   data_drive,data_dir,
  221.   work_drive,work_dir  : string;
  222.  
  223. Procedure Program_Initialize(program_name : string);
  224.  
  225. This unit is used to initialize most of the data structures specific to the
  226. SGP4 family of units.  The constant {max_sats} sets the limit (imposed by
  227. system memory constraints) on the maximum number of satellites available.
  228. This constant affects the storage allocation for two-line element sets in
  229. the array {sat_data}, satellite names in the array {sat_name}, and the array
  230. of selected satellites in {selected}.  Note that type {two_line} is a two-
  231. element string of 69-character lines.
  232.  
  233. The first variable provided is a boolean variable {visible} which is set
  234. when making calls to determine topocentric position; if the satellite is
  235. visible to the observer, {visible} is set true, otherwise it is set false.
  236. Checks of this variable make sense only in this context.  Eventually, this
  237. variable will also be used in determining other visibility conditions.
  238.  
  239. The next three variables pertain to the current two-line element set (the last
  240. one processed through Convert_Satellite_Data).  The variables {catnr} and
  241. {elset} are read from the appropriate field of Line 1 and serve to identify
  242. the data.  The variable {epoch} marks the epoch time (in two-line format) of
  243. that element set.
  244.  
  245. The final four variables are determined in the procedure Program_Initialize.
  246. They are used to specify the location of data files ({fsat} and {fobs} files)
  247. and output files.  Having separate locations for these two groups makes
  248. development and testing easier (in my opinion) and allows for standard
  249. locations to facilitate integration with other programs (it doesn't make sense
  250. to have various versions of two-line element set files scattered all over your
  251. hard disk).  These values are specified in the configuration file
  252. {program_name}.CFG (if it exists; if not, everything defaults to the working
  253. disk and directory).  For example, in the program TRAKSTAR, there would be a
  254. file TRAKSTAR.CFG which might look like:
  255.  
  256. d:
  257. \data\
  258. e:
  259. \work\
  260.  
  261. If this program were located in C:\SGP4 and the data was in C:\SGP4\DATA and
  262. work files were to go to C:\SGP4\WORK, the configuration file might look like:
  263.  
  264. c:
  265. \sgp4\data\
  266. c:
  267. \sgp4\work\
  268.  
  269. Note that each directory ends with a trailing \ (and should have no blanks).
  270. If you wish to run from the default drive (useful when using removable
  271. cartridges and moving between systems), you might change the above to:
  272.  
  273.  
  274. \sgp4\data\
  275.  
  276. \sgp4\work\
  277.  
  278. To specify directories which are below the working directory, you could also
  279. use:
  280.  
  281.  
  282. data\
  283.  
  284. work\
  285.  
  286. The call to Program_Initialize will read {program_name}.CFG to determine this
  287. information (if it exists) and will also read {program_name}.HDR (if it
  288. exists) to place one page of information on the screen to identify the
  289. program.  It is strongly recommended that these parameters be used in your
  290. programs to facilitate traceability and portability.
  291.  
  292. A call to Program_End is strongly recommended to reset the terminal after
  293. program execution.  Currently, this procedure positions the cursor to the
  294. bottom of the screen and makes sure it is on.
  295.  
  296. ** UNIT SGP_INTF -- VERSION 1.02 *********************************************
  297.  
  298. const
  299.   ae       = 1;
  300.   tothrd   = 2/3;
  301.   xkmper   = 6378.135;        {Earth equatorial radius - kilometers (WGS '72)}
  302.   f        = 1/298.26;        {Earth flattening (WGS '72)}
  303.   ge       = 398600.8;        {Earth gravitational constant (WGS '72)}
  304.   J2       = 1.0826158E-3;    {J2 harmonic (WGS '72)}
  305.   J3       = -2.53881E-6;     {J3 harmonic (WGS '72)}
  306.   J4       = -1.65597E-6;     {J4 harmonic (WGS '72)}
  307.   ck2      = J2/2;
  308.   ck4      = -3*J4/8;
  309.   xj3      = J3;
  310.   qo       = ae + 120/xkmper;
  311.   s        = ae + 78/xkmper;
  312.   e6a      = 1E-6;
  313.   dpinit   = 1;               {Deep-space initialization code}
  314.   dpsec    = 2;               {Deep-space secular code}
  315.   dpper    = 3;               {Deep-space periodic code}
  316.  
  317. var
  318.   iflag,ideep                : integer;
  319.   xmo,xnodeo,omegao,eo,xincl,
  320.   xno,xndt2o,xndd6o,bstar,
  321.   julian_epoch,xke           : double;
  322.  
  323. This unit defines the constants and variables used internal to SGP4SDP4.  Note
  324. that this version still uses WGS '72 values (while the impact of switching to
  325. WGS '84 is assessed).  It is STRONGLY recommended that this unit NOT be
  326. included in the main program.  All determinations using these constants (such
  327. as position of an observer on the earth's surface in the ECI system) should be
  328. performed through the appropriate call.  Also, note that {iflag} and {ideep}
  329. are unavailable to the main program under this recommendation, forcing the use
  330. of the procedure SGP to access the NORAD orbital models.
  331.  
  332. ** UNIT SGP_MATH -- VERSION 1.30 *********************************************
  333.  
  334. type
  335.   vector = array [1..4] of double;
  336.  
  337. const
  338.   twopi = 2 * pi;
  339.   zero : vector = (0,0,0,0);
  340.  
  341. Function Sign(arg : double) : shortint;
  342. Function Cube(arg : double) : double;
  343. Function Power(arg,pwr : double) : double;
  344. Function Radians(arg : double) : double;
  345. Function Degrees(arg : double) : double;
  346. Function Tan(arg : double) : double;
  347. Function ArcSin(arg : double) : double;
  348. Function ArcCos(arg : double) : double;
  349. Function Modulus(arg1,arg2 : double) : double;
  350. Function Fmod2p(arg : double) : double;
  351. Function AcTan(sinx,cosx : double) : double;
  352. Function Dot(v1,v2 : vector) : double;
  353. Procedure Magnitude(var v : vector);
  354. Procedure Cross(v1,v2 : vector; var v3 : vector);
  355.  
  356. This unit first defines the the type {vector} is as a four-element array (or
  357. four-vector) consisting (typically) of x, y, and z position and a vector
  358. magnitude.  These vectors are also used for storing other types of information
  359. (as will be seen in UNIT SGP_OBS).  Next, the constant {twopi} is defined as
  360. appropriate for Turbo Pascal Version 6.0.  Note that earlier versions of Turbo
  361. Pascal will NOT allow constant definitions of this form.  The definition of a
  362. zero vector has been added for this release.
  363.  
  364. The remaining routines are defined below.
  365.  
  366. Function Sign(arg : double) : shortint;
  367.      Output is the sign (-1, 0, +1) of {arg}.
  368. Function Cube(arg : double) : double;
  369.      Output is {arg} to the third power.
  370. Function Power(arg,pwr : double) : double;
  371.      Output is {arg} to the {pwr} power.  This is a more general-purpose
  372.      function, but is restricted to positive values of {arg}.  An error
  373.      message is reported if {arg} violates this restriction.
  374. Function Radians(arg : double) : double;
  375.      Output is an angle in radians where {arg} was input in degrees.
  376. Function Degrees(arg : double) : double;
  377.      Output is an angle is degrees where {arg} was input in radians.
  378. Function Tan(arg : double) : double;
  379.      Output is the tangent of {arg}.
  380. Function ArcSin(arg : double) : double;
  381.      Output is the arcsine of {arg} in radians.  Values range between -pi and
  382.      +pi.
  383. Function ArcCos(arg : double) : double;
  384.      Output is the arccosine of {arg} in radians.  Values range between 0 and
  385.      2*pi.
  386. Function Modulus(arg1,arg2 : double) : double;
  387.      Output is the remainder after {arg1} is divided by {arg2}.  This routine
  388.      is useful for keeping angles between 0 and 2*pi (or 0 and 360 degrees).
  389. Function Fmod2p(arg : double) : double;
  390.      This function is a specific implementation of Modulus where {arg2} equals
  391.      2*pi.  Used explicitly within SGP4SDP4.
  392. Function AcTan(sinx,cosx : double) : double;
  393.      Output is the arctangent of {sinx}/{cosx} in radians.  Used explicitly
  394.      within SGP4SDP4.  The advantage of this function over ArcTan is that it
  395.      returns the correct quadrant of the angle.
  396. Function Dot(v1,v2 : vector) : double;
  397.      Output is the vector dot product of {v1} and {v2}.
  398. Procedure Magnitude(var v : vector);
  399.      This procedure calculates the magnitude of vector {v} using components 1,
  400.      2, and 3, storing the result in component 4.
  401. Procedure Cross(v1,v2 : vector; var v3 : vector);
  402.      Returns vector {v3} which is the vector cross product of {v1} and {v2}.
  403.  
  404. ** UNIT SGP_OBS -- VERSION 1.40 **********************************************
  405.  
  406.   Uses SGP_Math;
  407.  
  408. Procedure Calculate_User_PosVel(var geodetic : vector;
  409.                                         time : double;
  410.                          var obs_pos,obs_vel : vector);
  411. Procedure Calculate_LatLonAlt(pos : vector;
  412.                              time : double;
  413.                      var geodetic : vector);
  414. Procedure Calculate_Obs(pos,vel,geodetic : vector;
  415.                                     time : double;
  416.                              var obs_set : vector);
  417. Procedure Calculate_RADec(pos,vel,geodetic : vector;
  418.                                       time : double;
  419.                                var obs_set : vector);
  420.  
  421. These procedures are used to provide observer-specific coordinate
  422. transformations of the output of the NORAD orbital models.
  423.  
  424. Procedure Calculate_User_PosVel passes the user's geodetic position and the
  425. time of interest and returns the ECI position and velocity of the observer.
  426. The format of {geodetic} is as explained in UNIT SGP_IN.  The velocity
  427. calculation assumes the geodetic position is stationary relative to the
  428. earth's surface.  This routine is made available to the user, although the
  429. exact nature of its application is uncertain.  This procedure is used,
  430. however, as the basis for Calculate_Obs and Calculate_RADec, to be explained
  431. later.
  432.  
  433. Procedure Calculate_LatLonAlt will calculate the {geodetic} position of an
  434. object given its ECI position {pos} and {time}.  It is intended to be used to
  435. determine the ground track of a satellite.  The calculations assume the earth
  436. to be an oblate spheroid as defined in WGS '72.
  437.  
  438. The procedures Calculate_Obs and Calculate_RADec calculate the *topocentric*
  439. coordinates of the object with ECI position, {pos}, and velocity, {vel}, from
  440. location {geodetic} at {time}.  The {obs_set} returned for Calculate_Obs
  441. consists of azimuth, elevation, range, and range rate (in that order) with
  442. units of radians, radians, kilometers, and kilometers/second, respectively.
  443. The WGS '72 geoid is used and the effect of atmospheric refraction (under
  444. standard temperature and pressure) is incorporated into the elevation
  445. calculation; the effect on range and range rate has not yet been quantified.
  446.  
  447. The {obs_set} for Calculate_RADec consists of right ascension and declination
  448. (in that order) in radians.  Again, calculations are based on *topocentric*
  449. position using the WGS '72 geoid and incorporating atmospheric refraction.
  450.  
  451. ** UNIT SGP_OUT -- VERSION 1.50 **********************************************
  452.  
  453.   Uses SGP_Math;
  454.  
  455. const
  456.   day_date  : boolean = true;
  457.   full_time : boolean = true;
  458.   N_E_W_S   : boolean = false;
  459.   D_M_S     : boolean = false;
  460.   time_res  : byte = 2;
  461.   angle_res : byte = 4;
  462.   dist_res  : byte = 3;
  463.  
  464. var
  465.   fout : text;
  466.  
  467. Procedure Output_Time(time : double);
  468. Procedure Output_ECI(time : double;
  469.                   pos,vel : vector);
  470. Procedure Output_Angle(angle : double;
  471.                    width,dec : byte;
  472.                      degrees : boolean);
  473. Procedure Output_LatLonAlt(time : double;
  474.                        geodetic : vector);
  475. Procedure Output_Obs(time : double;
  476.                       obs : vector);
  477. Procedure Output_RADec(time : double;
  478.                         obs : vector);
  479.  
  480. This unit begins with a set of constants used as formatting parameters.  The
  481. intention here is to set these values for consistency in the output and not
  482. clutter output calls with formatting information.  While the default values
  483. are set above, it is easy to change these values either globally or locally.
  484. For example, the user may decide to change these values in the program
  485. initialization step.  Or, these values could be set prior to making calls to
  486. routines within UNIT SGP_OUT.
  487.  
  488. The constant {day_date} allows for selection of output time as day/date (if
  489. true) or as a Julian Date (easier to read into other programs).
  490.  
  491. The constant {full_time} allows the selection of times with colons between the
  492. hours and minutes and between the minutes and seconds (i.e., HH:MM:SS), if set
  493. true.
  494.  
  495. The constant {N_E_W_S} is used with outputs of latitude and longitude to
  496. specify an output with North/South or East/West (if true) rather than plus or
  497. minus values.
  498.  
  499. The constant {D_M_S} allows for angular output in degrees, minutes, and
  500. seconds (if true) rather than decimal degrees.
  501.  
  502. The final three constants are used to set the precision of output for time,
  503. angle, and distance variables, respectively.  The default for {time_res} of 2
  504. indicates output to hundredths of a second.  The default for {angle_res} of 4
  505. indicates output to four decimal places (if D_M_S = false) or arcseconds (if
  506. D_M_S = true); outputs in degrees, minutes, and seconds are rounded to tens of
  507. arcminutes, arcminutes, tens of arcseconds, and seconds for values of 1, 2, 3,
  508. and 4, respectively.  The default for {dist_res} of 3 indicates a precision to
  509. three decimal places in distances (i.e., meters) and six decimal places in
  510. velocities (i.e., millimeters/second).
  511.  
  512. The variable {fout} is a pre-defined variable to specify the output file.
  513.  
  514. The procedure Output_Time is used to output either the calendar date and time
  515. of day or Julian Date of {time} to {fout}.
  516.  
  517. The procedure Output_ECI outputs ECI position {pos} (in kilometers) and
  518. velocity {vel} (in kilometers/second) vectors along with the time.
  519.  
  520. The procedure Output_Angle outputs an angle {angle} in a field of width
  521. {width} with {dec} decimal places.  The variable {degrees} is used when
  522. {D_M_S} is true to specify whether the angular output is degrees or hours.
  523.  
  524. The procedure Output_LatLonAlt output the time, latitude (in degrees),
  525. longitude (in degrees), and altitude (in kilometers) of an object.
  526.  
  527. The procedure Output_Obs outputs the time, azimuth (in degrees), elevation (in
  528. degrees), range (in kilometers), and range rate (in kilometers/second with
  529. negative values approaching the observer).
  530.  
  531. The procedure Output_RADec outputs the time, right ascension (in hours), and
  532. declination (in degrees).
  533.  
  534. Output_ECI and Output_LatLonAlt now write ECL at the end of each line if the
  535. satellite is in earth umbral eclipse.
  536.  
  537. Output_Obs and Output_RADec now output a blank line at the completion of a
  538. pass.
  539.  
  540. ** UNIT SGP_TIME -- VERSION 1.50 *********************************************
  541.  
  542.   Uses SGP_Math;
  543.  
  544. type
  545.   clock_time = string[12];
  546.   date       = string[11];
  547.  
  548. const
  549.   xmnpda   =  1440.0;        {Minutes per day}
  550.   secday   = 86400.0;        {Seconds per day}
  551.   omega_E  = 1.00273790934;  {Earth rotations per sidereal day (non-constant)}
  552.   omega_ER = omega_E*twopi;  {Earth rotation, radians per sidereal day}
  553.  
  554. var
  555.   ds50 : double;
  556.  
  557. Function Julian_Date_of_Year(year : double) : double;
  558. Function Julian_Date_of_Epoch(epoch : double) : double;
  559. Function Epoch_Time(jd : double) : double;
  560. Function DOY(yr,mo,dy : word) : word;
  561. Function Fraction_of_Day(hr,mi,se,hu : word) : double;
  562. Function Calendar_Date(jd : double) : date;
  563. Function Time_of_Day(jd : double;
  564.                    full : boolean;
  565.                     res : byte) : clock_time;
  566. Function ThetaG(epoch : double) : double;
  567. Function ThetaG_JD(jd : double) : double;
  568. Function Delta_ET(year : double) : double;
  569.  
  570. This unit contains all the routines to perform time conversions.
  571.  
  572. The function Julian_Date_of_Year calculates the Julian Date of Day 0.0 of
  573. {year}.  This function is used to calculate the Julian Date of any date by
  574. using Julian_Date_of_Year, DOY, and Fraction_of_Day.
  575.  
  576. The function Julian_Date_of_Epoch returns the Julian Date of an epoch
  577. specified in the format used in the NORAD two-line element sets.
  578.  
  579. The function DOY calculates the day of the year for the specified date.  The
  580. calculation uses the rules for the Gregorian calendar and is valid from the
  581. inception of that calendar system.
  582.  
  583. Fraction_of_Day calculates the fraction of a day passed at the specified input
  584. time.
  585.  
  586. The function Calendar_Date converts a Julian Date to a string of the form
  587. "yyyy Mon dd".  It is typically used as the major output time format.
  588.  
  589. Time_of_Day takes a Julian Date and calculates the clock time portion of that
  590. date.  The variable {full} is set true if it is desired to place colons
  591. between hours and minutes and minutes and seconds.  The variable {res} is used
  592. to determine the number of decimal places after the seconds in the output;
  593. zero gives a resolution of seconds, one gives a resolution of tenths of
  594. seconds, etc.  The variable {res} can take on values between 0 and 3.
  595.  
  596. The function ThetaG calculates the Greenwich Mean Sidereal Time for an epoch
  597. specified in the format used in the NORAD two-line element sets.  The function
  598. ThetaG_JD provides the same calculation except that it is based on an input in
  599. the form of a Julian Date.
  600.  
  601. The function Delta_ET has been added to allow calculations on the position of
  602. the sun.  It provides the difference between UT (approximately the same as UTC)
  603. and ET (now referred to as TDT).  This function is based on a least squares fit
  604. of data from 1950 to 1991 and will need to be updated periodically.
  605.  
  606. ** UNIT SOLAR -- VERSION 1.20 ************************************************
  607.  
  608.   Uses SGP_Math;
  609.  
  610. const
  611.   eclipsed : boolean = false;
  612.   show_vis : boolean = false;
  613.  
  614. var
  615.   civil,
  616.   nautical,
  617.   astronomical : double;  {Twilight elevations}
  618.   solar_pos    : vector;
  619.  
  620. Procedure Calculate_Solar_Position(time : double;
  621.                        var solar_vector : vector);
  622. Function Depth_of_Eclipse(time : double;
  623.                             r1 : vector) : double;
  624.  
  625. The variable {eclipsed} is provided for use with the Function Depth_of_Eclipse
  626. to reflect whether a satellite is in earth umbral eclipse.  The constant
  627. {show_vis} is used to indicate whether information should be output for all
  628. passes or only visible passes (i.e., satellite above the observer's horizon,
  629. not in earth umbral eclipse, and the sun below the appropriate threshold for
  630. skies to be dark at the observer's location).
  631.  
  632. The variables {civil}, {nautical}, and {astronomical} are initialized to the
  633. thresholds for solar elevation defining the corresponding twilights.  These
  634. are defined to occur at 6, 12, and 18 degrees below the horizon, respectively.
  635.  
  636. The variable {solar_pos} is provided to track the position of the sun as
  637. calculated in Depth_of_Eclipse, thus avoiding an additional call to
  638. Calculate_Solar_Position.
  639.  
  640. The procedure Calculate_Solar_Position calculates the position of the sun in
  641. the ECI coordinate system at the designated time (UTC).  The procedure makes
  642. an adjustment for the difference between UT and TDT by calling Delta_ET in
  643. Unit SGP_TIME.  The variable {solar_vector} returns the ECI position in
  644. kilometers and calculates the distance to the sun.
  645.  
  646. The function Depth_of_Eclipse calculates the distance an object at position
  647. {r1} at {time} is into the cone enclosing both the earth and the sun.  On the
  648. side of the earth away from the sun, this cone defines the earth's umbral
  649. shadow.  This distance is determined by first finding the perpendicular
  650. distance of the object from the line going through the centers of both the
  651. earth and the sun and then calculating the distance of the edge of the cone
  652. from this same line along the perpendicular.  The depth into eclipse is defined
  653. as the difference of these two distances.  Positive values reflect distances
  654. outside the eclipse zone.  Because the object can be within the cone on either
  655. side of the earth, the variable {eclipsed} is set true if the object is within
  656. the cone on the side of the earth opposite of the sun.
  657.  
  658. ** UNIT SUPPORT -- VERSION 1.81 **********************************************
  659.  
  660. const  {IBM PC screen codes}
  661.   BS       =  ^H;                      {Backspace}
  662.   CR       =  ^M;                      {Carriage Return}
  663.   CRLF     =  ^M^J;                    {Carriage Return/Line Feed}
  664.   BELL     =  ^G;                      {Terminal Bell}
  665.   ESC      =  ^[;                      {Escape}
  666.   DEL      =  #$7F;                    {Delete}
  667.   Up       =  #72;                     {Up Cursor}
  668.   Dn       =  #80;                     {Down Cursor}
  669.   Rt       =  #77;                     {Right Cursor}
  670.   Lt       =  #75;                     {Left Cursor}
  671.   Home     =  #71;                     {Home Key}
  672.   Endd     =  #79;                     {End Key}
  673.   PgUp     =  #73;                     {Page Up}
  674.   PgDn     =  #81;                     {Page Down}
  675.   C_Lt     =  #115;                    {Control-Left Cursor}
  676.   C_Rt     =  #116;                    {Control-Right Cursor}
  677.   C_PgUp   =  #132;                    {Control-Page Up}
  678.   C_PgDn   =  #118;                    {Control-Page Down}
  679.   UpDown   =  #24#25;                  {Up/Down Arrows}
  680.   Cursors  =  #24#25#26#27;            {Up/Down/Left/Right Arrows}
  681.   SFrame : string = '┌─┐│└┘┴┬├┼┤';     {Single-Line Frame Characters}
  682.   DFrame : string = '╔═╗║╚╝╩╦╠╬╣';     {Double-Line Frame Characters}
  683.   MFrame : string = '╡╞╕╛╘╒';          {Mixed-Line Frame Characters}
  684.  
  685. type
  686.   options  = array [0..10] of string;
  687.   time_set = record
  688.     yr,mo,dy,hr,mi,se,hu : word;
  689.     end; {record}
  690.  
  691. Procedure Cursor_On;
  692. Procedure Cursor_Off;
  693. Procedure Save_Cursor;
  694. Procedure Restore_Cursor;
  695. Procedure ReverseVideo;
  696. Procedure NormalVideo;
  697. Procedure BoldVideo;
  698. Procedure FrameWindow(x,y,w,h,color : byte; title : string);
  699. Procedure MakeWindow(x,y,w,h,color : byte; title : string);
  700. Procedure ClearWindow(x,y,w,h : byte);
  701. Procedure Show_Status_Line(title : string);
  702. Procedure Show_Instructions(title : string);
  703. Procedure Clear_Status_Line;
  704. Procedure Report_Error(x,y : byte; title : string);
  705. Procedure Beep;
  706. Procedure Buzz;
  707. Procedure Mark_Time;
  708. Procedure Zero_Time(var time : time_set);
  709. Procedure Get_Current_Time(var time : time_set);
  710. Function Yes : boolean;
  711. Function TwoDigit(arg : integer) : string;
  712. Function ThreeDigit(arg : integer) : string;
  713. Procedure Convert_Blanks(var field : string);
  714. Function Integer_Value(buffer : string;
  715.                  start,length : integer) : integer;
  716. Function Real_Value(buffer : string;
  717.               start,length : integer) : double;
  718. Function File_Exists(filename : string) : boolean;
  719. Function Select_File(title,pattern,default : string; x,y,w,h : byte) : string;
  720. Function Select_Option(menu : options; number,x,y,w,h : byte) : byte;
  721.  
  722. This unit is considerably different from the other units in this library and
  723. is intended to be a general support library for a specific hardware
  724. implementation, in this case the IBM PC compatible family of microcomputers
  725. running Microsoft DOS.  Eventually, *ALL* machine-specific code will be put in
  726. this unit to enhance portability, meaning that only these routines will have
  727. to be changed to port it to another machine.  I have decided not to delay the
  728. release of the package to achieve this goal since there is no widely available
  729. standard implementation of Pascal to necessitate such changes.  However, when
  730. these units are converted to C, all machine-specific routines will be limited
  731. to this unit.
  732.  
  733. The unit begins with a set of constants which define the specifics of various
  734. keys and characters on IBM PCs; their definitions are commented above.
  735.  
  736. The two types defined are an array of {options} which are used with the
  737. function Select_Option and {time_set} which is a record containing the year,
  738. month, day, hour, minute, second, and hundredth of seconds.
  739.  
  740. The remaining routines are described below.
  741.  
  742. Procedure Cursor_On;
  743.      Turns on a block cursor on the screen at the current cursor location.
  744. Procedure Cursor_Off;
  745.      Hides the cursor from view.
  746. Procedure Save_Cursor;
  747.      Saves the current position of the cursor.
  748. Procedure Restore_Cursor;
  749.      Restores the cursor location to the last saved location.
  750. Procedure ReverseVideo;
  751.      Changes the text attributes to reverse video (black on white).
  752. Procedure NormalVideo;
  753.      Changes the text attributes to normal_video (white on black).
  754. Procedure BoldVideo;
  755.      Changes the text attributes to bold (yellow on black).
  756. Procedure FrameWindow(x,y,w,h,color : byte; title : string);
  757.      Puts a frame around a window (and is usually called by MakeWindow).
  758. Procedure MakeWindow(x,y,w,h,color : byte; title : string);
  759.      Makes a window, located at ({x},{y}) with width {w} and height {h} in
  760.      color {color}.  A {title} is put on the window.
  761. Procedure ClearWindow(x,y,w,h : byte);
  762.      ClearWindow simply clears a window from the display.  The code does not,
  763.      at this time, allow restoration of underlying screen text.
  764. Procedure Show_Status_Line(title : string);
  765.      Shows status on the left side of the last line of the display.  Usually
  766.      used in support of providing brief instructions during input.
  767. Procedure Show_Instructions(title : string);
  768.      Similar to Show_Status_Line except providing right-justified output on
  769.      the last line of the display.
  770. Procedure Clear_Status_Line;
  771.      Clears the last line of the display.
  772. Procedure Report_Error(x,y : byte; title : string);
  773.      Reports the error specified by {title} in BoldVideo at the position
  774.      ({x},{y}) and then exits the program.
  775. Procedure Beep;
  776.      Sounds a high-pitched tone to draw attention.
  777. Procedure Buzz;
  778.      Sounds a lower-pitched tone to indicate an error condition.
  779. Procedure Mark_Time;
  780.      A rotating cursor to serve as a visual indication that the machine is
  781.      still operating during time-intensive operations.
  782. Procedure Zero_Time(var time : time_set);
  783.      Places zeros in all element of {time}.  Useful in initializing in
  784.      preparation for a call to Select_Time_Interval.
  785. Procedure Get_Current_Time(var time : time_set);
  786.      Reads the current system time into variable {time}.  Useful for
  787.      initializing Select_Time.
  788. Function Yes : boolean;
  789.      A function which waits for the input of a Y or N in response to a
  790.      question.  The words Yes or No are printed in response to the appropriate
  791.      input and Yes is set true if a positive response is received.  For
  792.      example,
  793.  
  794.      Write('Are you ready? ');
  795.      if Yes then Do_Ready else Do_Not_Ready;
  796.  
  797. Function TwoDigit(arg : integer) : string;
  798.      Converts an integer to a two-digit string with leading zeros.
  799. Function ThreeDigit(arg : integer) : string;
  800.      Converts an integer to a three-digit string with leading zeros.
  801. Procedure Convert_Blanks(var field : string);
  802.      Used with the next two functions to convert leading spaces to zeros to
  803.      facilitate text conversion to integers or reals.
  804. Function Integer_Value(buffer : string;
  805.                  start,length : integer) : integer;
  806.      Takes the segment of {buffer} beginning at {start} and having length
  807.      {length} and converts it to an integer number.
  808. Function Real_Value(buffer : string;
  809.               start,length : integer) : double;
  810.      Takes the segment of {buffer} beginning at {start} and having length
  811.      {length} and converts it to a double precision real number.
  812. Function File_Exists(filename : string) : boolean;
  813.      Checks to see if {filename} exists.
  814. Function Select_File(title,pattern,default : string; x,y,w,h : byte) : string;
  815.      Allows for easy selection of input files.  Select_File places a window on
  816.      the screen with upper-left corner at location ({x},{y}) and having width
  817.      {w} and maximum height of {h}.  The window is labeled with {title} and
  818.      {pattern} specifies the pattern of files to look for; {default} is the
  819.      default pattern (this filename is highlighted, if present).  Select_File
  820.      returns the filename selected.
  821. Function Select_Option(menu : options; number,x,y,w,h : byte) : byte;
  822.      Allows for the easy selection of an option from a menu {menu}.  The
  823.      values of {x}, {y}, {w}, and {h} are the same as for Select_File;
  824.      {number} indicates the total number of options available.  Select_Option
  825.      returns the option number selected.
  826.